package com.genersoft.iot.vmp.vmanager.gb28181.media;

import com.alibaba.fastjson.JSONObject;
import com.genersoft.iot.vmp.common.ResultCode;
import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
import com.genersoft.iot.vmp.gb28181.utils.SignUtil;
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import com.genersoft.iot.vmp.service.IMediaService;
import com.genersoft.iot.vmp.service.IPlayService;
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.async.DeferredResult;

import java.util.HashMap;
import java.util.Map;


@Api(tags = "媒体流相关")
@Controller
@CrossOrigin
@RequestMapping(value = "/api/media")
public class MediaController {

    private final static Logger logger = LoggerFactory.getLogger(MediaController.class);

    @Autowired
    private IVideoManagerStorager storager;

    @Autowired
    private IMediaService mediaService;
    @Autowired
    private IPlayService playService;
    @Autowired
    private DeferredResultHolder resultHolder;


    /**
     * 根据应用名和流id获取播放地址
     * @param app 应用名
     * @param stream 流id
     * @return
     */
    @ApiOperation("根据应用名和流id获取播放地址")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "app", value = "应用名", dataTypeClass = String.class),
            @ApiImplicitParam(name = "stream", value = "流id", dataTypeClass = String.class),
            @ApiImplicitParam(name = "mediaServerId", value = "媒体服务器id", dataTypeClass = String.class),
    })
    @GetMapping(value = "/stream_info_by_app_and_stream")
    @ResponseBody
    public WVPResult<StreamInfo> getStreamInfoByAppAndStream(@RequestParam String app, @RequestParam String stream, @RequestParam String mediaServerId){
        StreamInfo streamInfoByAppAndStreamWithCheck = mediaService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId);
        WVPResult<StreamInfo> result = new WVPResult<>();
        if (streamInfoByAppAndStreamWithCheck != null){
            result.setCode(0);
            result.setMsg("scccess");
            result.setData(streamInfoByAppAndStreamWithCheck);
        }else {
            result.setCode(-1);
            result.setMsg("fail");
        }
        return result;
    }

//    @GetMapping(value = "/play")
//    @ResponseBody
//    public DeferredResult<ResponseEntity<String>> play(@RequestParam String deviceId,
//                                                        @RequestParam String channelId) {
//
//        // 获取可用的zlm
//        Device device = storager.queryVideoDevice(deviceId);
//        MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device);
//        PlayResult playResult = playService.play(newMediaServerItem, deviceId, channelId, null, null);
//        logger.info("playResult {}",playResult.getResult());
//        return playResult.getResult();
//    }

    @GetMapping({"/play"})
    @ResponseBody
    public DeferredResult<ResponseEntity<String>> play(@RequestParam String deviceId, @RequestParam String channelId, @RequestParam(required = false) String stream, @RequestParam String time, @RequestParam String sign) {
        Device device = this.storager.queryVideoDevice(deviceId);
//        Map<String, String> signParam = new HashMap<>();
//        signParam.put("deviceId", deviceId);
//        signParam.put("channelId", channelId);
//        signParam.put("time", time);
        DeferredResult<ResponseEntity<String>> result = new DeferredResult();
        WVPResult wvpResult = new WVPResult();
       /* if (!"testSign".equals(sign) && !SignUtil.signCheck(signParam, device.getPrivateKey(), sign)) {
            this.resultHolder.put(DeferredResultHolder.SIGN_CHECK + deviceId, result);
            RequestMessage msg = new RequestMessage();
            msg.setId(DeferredResultHolder.SIGN_CHECK + deviceId);
            wvpResult.setValue(ResultCode.SIGN_ERROR);
            msg.setData(wvpResult);
            this.resultHolder.invokeResult(msg);
            return result;
        }*/
        MediaServerItem newMediaServerItem = this.playService.getNewMediaServerItem(device);
        PlayResult playResult = this.playService.play(newMediaServerItem, deviceId, channelId,stream, null, null);
        logger.info("playResult {}", playResult.getResult());
        return playResult.getResult();
    }


    /**
     * 通道快照
     * @param deviceId
     * @param channelId
     * @param stream
     * @param time
     * @param sign
     * @return
     */
    @GetMapping({"/channelSnap"})
    @ResponseBody
    public ResponseEntity<WVPResult<String>> channelSnap(@RequestParam String deviceId, @RequestParam String channelId, @RequestParam(required = true) String stream, @RequestParam String time, @RequestParam String sign) {
        Device device = this.storager.queryVideoDevice(deviceId);
//        Map<String, String> signParam = new HashMap<>();
//        signParam.put("deviceId", deviceId);
//        signParam.put("channelId", channelId);
//        signParam.put("time", time);
        WVPResult wvpResult = new WVPResult();
        JSONObject data = new JSONObject();

       /* if (!"testSign".equals(sign) && !SignUtil.signCheck(signParam, device.getPrivateKey(), sign)) {
            wvpResult.setCode(ResultCode.SIGN_ERROR.getCode());
            wvpResult.setMsg(ResultCode.SIGN_ERROR.getMsg());

            wvpResult.setData(data);
            return new ResponseEntity<>(wvpResult, HttpStatus.OK);
        }*/

        try{
             data.put("snapUrl", playService.channelSnap(deviceId,channelId,stream));
        }catch (Exception ex){
            ex.printStackTrace();
            wvpResult.setCode(ResultCode.NOTFOUND_CODE.getCode());
            wvpResult.setMsg(ResultCode.NOTFOUND_CODE.getMsg());
            wvpResult.setData(data);
            return new ResponseEntity<>(wvpResult, HttpStatus.OK);
        }
        wvpResult.setCode(ResultCode.OK.getCode());
        wvpResult.setMsg(ResultCode.OK.getMsg());
        wvpResult.setData(data);
        return new ResponseEntity<>(wvpResult, HttpStatus.OK);
    }

}
